#include <QStyle>
#include <QDebug>
#include <QLabel>
#include "kdisplayview.h"



// 构造函数：初始化窗口和各部分布局
DisplayView::DisplayView(QWidget* parent)
    : QWidget(parent),
    m_pprocessLineEdit(new QLineEdit(this)),
    m_pdisplayLineEdit(new QLineEdit(this)),
    m_phistoryButton(new QPushButton(this))
{
//设置窗口属性（图标、大小、背景色）
    setupWindowProperties();
//初始化主布局拉伸参数
    setupMainLayout();      
//初始化顶部栏（包括历史记录按钮）
    setupTopBar();      
//初始化计算表达式显示栏
    setupHistoryDisplay();
//初始化主结果显示栏
    setupResultDisplay();       
//创建所有算数按钮
    createButtons();
//历史记录栏初始化
    setupHistoryPopup();     

}

//设置窗口属性（图标、大小、背景色）
void DisplayView::setupWindowProperties()
{
    setMinimumSize(560, 840);
    setStyleSheet("background-color: #f2f2f2;");
    setWindowIcon(QIcon(":/icons/calculator.png"));
    setWindowTitle("Calculator");
}

//设置主布局拉伸策略
void DisplayView::setupMainLayout()
{
    auto* layout = new QGridLayout(this);
    layout->setContentsMargins(8, 8, 8, 8);
    layout->setSpacing(6);
    //在窗口拉伸时不会自动变高
    layout->setRowStretch(0, 0);
    layout->setRowStretch(1, 0);
    layout->setRowStretch(2, 0);
    //在窗口变高时平均地拉伸增长
    for (int r = 3; r < 10; ++r)
        layout->setRowStretch(r, 1);
    //所有列等比例拉伸
    for (int c = 0; c < 4; ++c)
        layout->setColumnStretch(c, 1);
}

//初始化顶部栏（包括模式与历史按钮）
void DisplayView::setupTopBar()
{
    QHBoxLayout* topBarLayout = new QHBoxLayout(this);

    QLabel* modeLabel = new QLabel("Standard", this);
    modeLabel->setStyleSheet("color: black; font-weight: bold; font-size: 28px;");

    m_phistoryButton->setIcon(QIcon(":/icons/historyButton.png"));
    m_phistoryButton->setFixedSize(32, 32);
    m_phistoryButton->setStyleSheet(
        "QPushButton { border: none; background: transparent; }"
        "QPushButton:hover { background-color: #e0e0e0; border-radius: 8px; }"
    );

    topBarLayout->addWidget(modeLabel);
    topBarLayout->addStretch();
    topBarLayout->addWidget(m_phistoryButton);

    QWidget* topBarWidget = new QWidget(this);
    topBarWidget->setLayout(topBarLayout);
    static_cast<QGridLayout*>(layout())->addWidget(topBarWidget, 0, 0, 1, 4);
}

//设置历史记录显示栏属性并加入布局
void DisplayView::setupHistoryDisplay()
{
    m_pprocessLineEdit->setReadOnly(true);
    m_pprocessLineEdit->setAlignment(Qt::AlignRight);
    m_pprocessLineEdit->setFrame(false);
    m_pprocessLineEdit->setStyleSheet(
        "QLineEdit {"
        "   background: transparent;"
        "   border: none;"
        "   color: gray;"
        "}"
    );
    static_cast<QGridLayout*>(layout())->addWidget(m_pprocessLineEdit, 1, 0, 1, 4);
}

//设置主显示区域属性并加入布局
void DisplayView::setupResultDisplay()
{
    m_pdisplayLineEdit->setReadOnly(true);
    m_pdisplayLineEdit->setAlignment(Qt::AlignRight);
    m_pprocessLineEdit->setFrame(false);
    m_pdisplayLineEdit->setStyleSheet(
        "QLineEdit {"
        "   background-color: #f2f2f2;"
        "   border: none;"
        "   color: black;"
        "}"
    );
    static_cast<QGridLayout*>(layout())->addWidget(m_pdisplayLineEdit, 2, 0, 1, 4);
}

//根据窗口大小动态调整字体大小
void DisplayView::updateFontSize()
{
    const int minHeightForLargeFont = 1000;
    if (height() >= minHeightForLargeFont) {
        setLargeFont();
    }
    else {
        setSmallFont();
    }
}

//设置为大字体
void DisplayView::setLargeFont()
{
    m_pprocessLineEdit->setFont(QFont("Arial Unicode MS", 18));
    m_pdisplayLineEdit->setFont(QFont("Arial Unicode MS", 32));
    for (auto* button : m_pbuttons) {
        button->setFont(QFont("Arial", 18));
    }
}

//设置为小字体
void DisplayView::setSmallFont()
{
    m_pprocessLineEdit->setFont(QFont("Arial Unicode MS", 14));
    m_pdisplayLineEdit->setFont(QFont("Arial Unicode MS", 24));
    for (auto* button : m_pbuttons) {
        button->setFont(QFont("Arial", 12));
    }
}

//窗口尺寸变化时调整字体大小
void DisplayView::resizeEvent(QResizeEvent* event)
{
    QWidget::resizeEvent(event);
    updateFontSize();
}

//创建所有按钮并添加到主布局，我这里直接这么添加的话省了很多button，但是我不知道这是好事还是坏事，如果您看到这里请提点我一下！
void DisplayView::createButtons()
{
    //部分字符用Unicode转义字符定义，用来显示
    const ButtonInfo infos[7][4] = {
        { {"CE", "CE", QIcon()}, {"C", "C", QIcon()}, {"back", "back", QIcon(":/icons/back.png")}, {"forward", "forw", QIcon(":/icons/forward.png")} },
        { {"inv", "1/x", QIcon()}, {"sqr", QStringLiteral("x") + QChar(0x00B2), QIcon()}, {"sqrt", QStringLiteral("\u221Ax"), QIcon()}, {"del", "Del", QIcon(":/icons/delete.png")} },
        { {"neg", "+/-", QIcon()}, {".", ".", QIcon()}, {"pct", "%", QIcon()}, {"/", "/", QIcon()} },
        { {"7", "7", QIcon()}, {"8", "8", QIcon()}, {"9", "9", QIcon()}, {"*", "*", QIcon()} },
        { {"4", "4", QIcon()}, {"5", "5", QIcon()}, {"6", "6", QIcon()}, {"-", "-", QIcon()} },
        { {"1", "1", QIcon()}, {"2", "2", QIcon()}, {"3", "3", QIcon()}, {"+", "+", QIcon()} },
        { {"(", "(", QIcon()}, {"0", "0", QIcon()}, {")", ")", QIcon()}, {"=", "=", QIcon()} }
    };

    for (int r = 0; r < 7; ++r) {
        for (int c = 0; c < 4; ++c) {
            QPushButton* button = createButton(infos[r][c]);
            button->setProperty("row", r);
            button->setProperty("col", c);
            static_cast<QGridLayout*>(layout())->addWidget(button, r + 3, c);
            m_pbuttons << button;
        }
    }
}

//创建单个按钮
QPushButton* DisplayView::createButton(const ButtonInfo& info)
{
    QPushButton* button = new QPushButton(this);
    button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    setupButtonContent(button, info);
    setupButtonStyle(button, info);
    //给这个按钮设置了一个叫做token的属性，值是info.token，用来在计算中处理，比如根号无法在计算中处理，可以赋值sqrt，但是显示用unicode
    button->setProperty("token", info.token);
    return button;
}

//设置按钮内容（文字或图标）
void DisplayView::setupButtonContent(QPushButton* button, const ButtonInfo& info)
{
    if (!info.icon.isNull()) {
        button->setIcon(info.icon);
    }
    else {
        button->setText(info.displayText);
    }
}

//设置按钮样式（颜色、边框、圆角等）
void DisplayView::setupButtonStyle(QPushButton* button, const ButtonInfo& info)
{
    const QString baseStyle =
        "QPushButton {"
        "   border-radius: 12px;" 
        "   border: 1px solid #e0e0e0;"  
        "   font: inherit;" // 继承父控件的字体设置
        "}"
        "QPushButton:hover {" // 当鼠标悬停时，设置垂直线性渐变背景
        "   background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #f5f5f5, stop:1 #e5e5e5);"
        "}";
    //单独对等号处理
    if (info.token == "=") {
        button->setStyleSheet(
            "QPushButton {"
            "   background-color: #666666;"
            "   color: white;"
            "   border-radius: 12px;"
            "   border: none;"
            "}"
            "QPushButton:hover { background-color: #5a5a5a; }"
        );
        return;
    }
    //从按钮中读取自定义属性 row 和 col，然后转换成整数类型
    int row = button->property("row").toInt();
    int col = button->property("col").toInt();

    if (info.token.toInt() || info.token == "0") {
        button->setStyleSheet(baseStyle + "QPushButton { background-color: white; }");
    }
    else if (isOperatorOrFunction(info.token)) {
        button->setStyleSheet(baseStyle + "QPushButton { background-color: #f5f5f5; }");
    }
    else {
        button->setStyleSheet(baseStyle + "QPushButton { background-color: white; }");
    }
}

//判断按钮是否为运算符/函数
bool DisplayView::isOperatorOrFunction(const QString& token)
{
    static const QSet<QString> operators{
        "+", "-", "*", "/", "CE", "C", "back", "forward", "pct", "inv", "sqr", "sqrt", "del", "neg", "."
    };
    return operators.contains(token);
}

//设置主结果栏内容
void DisplayView::setExpression(const QString& expr) {
    m_pdisplayLineEdit->setText(expr);
}

//设置历史表达式栏内容
void DisplayView::setProcessExpression(const QString& history) {
    m_pprocessLineEdit->setText(history);
}

//获取所有按钮（用于绑定信号）
QList<QPushButton*> DisplayView::allButtons() const {
    return m_pbuttons;
}

//初始化历史记录弹出层
void DisplayView::setupHistoryPopup() {
    m_phistoryPopup = new HistoryPopup(this);
}

//获取按钮区域顶部 y 坐标（用于弹出动画）
int DisplayView::getButtonAreaTop() const {
    if (m_pbuttons.isEmpty()) return height();
    const QPushButton* firstButton = m_pbuttons.first(); //获取第一个按钮，也就是最高的那个
    QPoint globalPos = firstButton->mapTo(this, QPoint(0, 0));
    return globalPos.y();
}

//获取历史栏切换按钮
QPushButton* DisplayView::historyToggleButton() const {
    return m_phistoryButton;
}

//获取历史记录弹出层对象
HistoryPopup* DisplayView::historyPopup() const {
    return m_phistoryPopup;
}
